package com.css.zfzx.fwsjcj.modules.structure.service.impl;

import cn.afterturn.easypoi.excel.ExcelImportUtil;
import cn.afterturn.easypoi.excel.entity.ImportParams;
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
import com.alibaba.fastjson.JSONObject;
import com.css.bpm.platform.api.local.PlatformAPI;
import com.css.bpm.platform.components.attach.repository.entity.SysAttachmentEntity;
import com.css.bpm.platform.components.attach.service.SysAttachment;
import com.css.bpm.platform.org.division.repository.entity.DivisionEntity;
import com.css.bpm.platform.org.user.repository.entity.UserEntity;
import com.css.bpm.platform.utils.PlatformObjectUtils;
import com.css.bpm.platform.utils.PlatformSessionUtils;
import com.css.bpm.platform.utils.UUIDGenerator;
import com.css.zfzx.fwsjcj.cache.DivisionCache;
import com.css.zfzx.fwsjcj.commen.util.Constant;
import com.css.zfzx.fwsjcj.commen.util.EasyPoiExcelUtil;
import com.css.zfzx.fwsjcj.modules.analysis.vo.AnalysisQueryVo;
import com.css.zfzx.fwsjcj.modules.structure.entity.FwOtherStructureEntity;
import com.css.zfzx.fwsjcj.modules.structure.entity.FwStructureFormEntity;
import com.css.zfzx.fwsjcj.modules.structure.entity.QFwOtherStructureEntity;
import com.css.zfzx.fwsjcj.modules.structure.repository.FwOtherStructureRepository;
import com.css.zfzx.fwsjcj.modules.structure.repository.FwStructureFormRepository;
import com.css.zfzx.fwsjcj.modules.structure.service.FwOtherStructureService;
import com.css.zfzx.fwsjcj.modules.structure.service.FwStructureFormService;
import com.css.zfzx.fwsjcj.modules.structure.verify.BrickStructureCheck;
import com.css.zfzx.fwsjcj.modules.structure.verify.OtherStructureCheck;
import com.css.zfzx.fwsjcj.modules.structure.vo.FwOtherStructureVo;
import com.css.zfzx.fwsjcj.modules.structure.vo.StructureQueryVo;

import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author ly
 * @Title: FwBrickStructureServiceImpl
 * @Description: 其它结构
 * @date 2020/6/3 10:09
 */
@Slf4j
@Service
public class FwOtherStructureServiceImpl implements FwOtherStructureService {
    @Autowired
    private FwOtherStructureRepository otherStructureRepository;
    @Autowired
    private JPAQueryFactory jpaQueryFactory;
    @Autowired
    private FwStructureFormService structureFormService;
    @Autowired
    private FwStructureFormRepository fwStructureFormRepository;
    @Resource
    private SysAttachment sysAttachment;

    private volatile static HashMap<String, List> divisionMap;

    @Override
    @Transactional
    public void save(FwOtherStructureEntity fwOtherStructureEntity) {
        String userId = PlatformSessionUtils.getUserId();
        UserEntity user = PlatformAPI.getOrgAPI().getUserAPI().getUser(userId);
        /**
         * 砖石结构子表设置默认值（子表保存）
         */
        fwOtherStructureEntity.setId(UUIDGenerator.getUUID());
        // 数据收集人名称
        fwOtherStructureEntity.setCollectUser(user.getUserName());
        // 存数据收集人ID
        fwOtherStructureEntity.setCreateUser(userId);
        fwOtherStructureEntity.setCreateTime(new Date());
        fwOtherStructureEntity.setDelFlag(Constant.DEL_NO);
        otherStructureRepository.save(fwOtherStructureEntity);

        /**
         * 主表保存
         */
        FwStructureFormEntity structureFormEntity = new FwStructureFormEntity();
        // 保存子表ID
        structureFormEntity.setStructureId(fwOtherStructureEntity.getId());
        // 保存子表类型
        structureFormEntity.setStructureType(Constant.OTHER_STRUCTURE);
        // 保存子表省、市、区县
        structureFormEntity.setBelongtoProvince(fwOtherStructureEntity.getBelongtoProvince());
        structureFormEntity.setBelongtoCity(fwOtherStructureEntity.getBelongtoCity());
        structureFormEntity.setBelongtoArea(fwOtherStructureEntity.getBelongtoArea());
        // 保存子表建筑名称
        structureFormEntity.setBuildingName(fwOtherStructureEntity.getBuildingName());
        // 保存子表建筑类型
        structureFormEntity.setSiteType(fwOtherStructureEntity.getSiteType());
        // 保存建筑编号
        structureFormEntity.setStructureNum(fwOtherStructureEntity.getOtherStructureNum());
        // 保存任务id和名称
        structureFormEntity.setTaskId(fwOtherStructureEntity.getTaskId());
        structureFormEntity.setTaskName(fwOtherStructureEntity.getTaskName());
        structureFormEntity.setBuildingArea(fwOtherStructureEntity.getBuildingArea()==null?0.0:fwOtherStructureEntity.getBuildingArea());
        structureFormEntity.setStatus(fwOtherStructureEntity.getStatus());
        structureFormService.save(structureFormEntity);
    }

    @Override
    @Transactional
    public void update(FwOtherStructureEntity fwOtherStructureEntity) {
        if (StringUtils.isEmpty(fwOtherStructureEntity.getId())) {
            throw new RuntimeException("修改ID不能为空");
        }
        // 获取当前用户信息
        String userId = PlatformSessionUtils.getUserId();
        UserEntity user = PlatformAPI.getOrgAPI().getUserAPI().getUser(userId);
        /**
         * 设置默认值
         */
        fwOtherStructureEntity.setUpdateUser(user.getUserId());
        fwOtherStructureEntity.setUpdateTime(new Date());
        // 将不为空的数据拷贝到旧数据中
        //FwOtherStructureEntity oldTarge = this.findById(fwOtherStructureEntity.getId());
        // 若审核状态为审核未通过改为未提交
        if(Constant.SP_NOT.equals(fwOtherStructureEntity.getStatus())){
            fwOtherStructureEntity.setStatus(Constant.NO_SUB);
            fwOtherStructureEntity.setCheckOpinion("");
            fwOtherStructureEntity.setCheckUser("");
        }
        //SpringUtil.copyPropertiesIgnoreEmpty(fwOtherStructureEntity, oldTarge);
        // 实体中必须有ID
       otherStructureRepository.save(fwOtherStructureEntity);

        /**
         * 主表保存
         */
        FwStructureFormEntity sourceStructureFormEntity = structureFormService.findStructureForm(Constant.OTHER_STRUCTURE, fwOtherStructureEntity.getId());
        //FwStructureFormEntity targetStructureFormEntity = sourceStructureFormEntity;
        // 保存子表省
        sourceStructureFormEntity.setBelongtoProvince(fwOtherStructureEntity.getBelongtoProvince());
        // 保存子表市
        sourceStructureFormEntity.setBelongtoCity(fwOtherStructureEntity.getBelongtoCity());
        // 保存子表区县
        sourceStructureFormEntity.setBelongtoArea(fwOtherStructureEntity.getBelongtoArea());
        // 保存子表建筑名称
        sourceStructureFormEntity.setBuildingName(fwOtherStructureEntity.getBuildingName());
        // 保存子表建筑类型
        sourceStructureFormEntity.setSiteType(fwOtherStructureEntity.getSiteType());
        // 若审核状态为审核未通过改为未提交
        if (Constant.SP_NOT.equals(sourceStructureFormEntity.getStatus())){
            sourceStructureFormEntity.setStatus(Constant.NO_SUB);
            sourceStructureFormEntity.setCheckUser("");
            sourceStructureFormEntity.setCheckOpinion("");
        }
        sourceStructureFormEntity.setStatus(fwOtherStructureEntity.getStatus());
        sourceStructureFormEntity.setBuildingArea(fwOtherStructureEntity.getBuildingArea()==null?0.0:fwOtherStructureEntity.getBuildingArea());
        structureFormService.update(sourceStructureFormEntity);
    }


    @Override
    public JSONObject getPage(StructureQueryVo structureQueryVo, int curPage, int pageSize) {
        QFwOtherStructureEntity q = QFwOtherStructureEntity.fwOtherStructureEntity;
        Predicate predicate = q.isNotNull().or(q.isNull());

        // 查询条件
        if (structureQueryVo != null) {
            String buildingName = structureQueryVo.getBuildingName();
            predicate = StringUtils.isEmpty(buildingName) ? predicate : ExpressionUtils.and(predicate, q.buildingName.like("%" + buildingName + "%"));

            String belongtoProvince = structureQueryVo.getBelongtoProvince();
            predicate = StringUtils.isEmpty(belongtoProvince) ? predicate : ExpressionUtils.and(predicate, q.belongtoProvince.like("%" + belongtoProvince + "%"));

            String belongtoCity = structureQueryVo.getBelongtoCity();
            predicate = StringUtils.isEmpty(belongtoCity) ? predicate : ExpressionUtils.and(predicate, q.belongtoCity.like("%" + belongtoCity + "%"));

            String siteType = structureQueryVo.getSiteType();
            predicate = StringUtils.isEmpty(siteType) ? predicate : ExpressionUtils.and(predicate, q.siteType.like("%" + siteType + "%"));

            String status = structureQueryVo.getStatus();
            predicate = StringUtils.isEmpty(status) ? predicate : ExpressionUtils.and(predicate, q.status.eq(status));

        }
        // 删除标识
        predicate = ExpressionUtils.and(predicate, q.delFlag.eq(Constant.DEL_NO));

        QueryResults<FwOtherStructureEntity> page = jpaQueryFactory
                .selectFrom(q)
                .where(predicate)
                .orderBy(q.createTime.desc())
                .offset(curPage - 1)   //起始页
                .limit(pageSize)  //每页大小
                .fetchResults();
        //适配base转为JSONObject类型
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("rows", page.getResults());
        jsonObject.put("total", page.getTotal());
        return jsonObject;
    }

    @Override
    public void delete(String id) {
        FwOtherStructureEntity otherStructureEntity = otherStructureRepository.findById(id).get();
        otherStructureEntity.setDelFlag(Constant.DEL_YES);
        update(otherStructureEntity);
    }

    @Override
    public FwOtherStructureEntity findById(String id) {
        return otherStructureRepository.findById(id).get();
    }

    @Override
    public List<FwOtherStructureEntity> findAll() {
        //return brickStructureRepository.findById(id).get();
        return otherStructureRepository.findAll();
    }

    @Override
    @Transactional
    public void submit(List<String> idList) {
        QFwOtherStructureEntity q = QFwOtherStructureEntity.fwOtherStructureEntity;
        jpaQueryFactory.update(q)
                .set(q.status, Constant.DAI_SP)
                .where(q.id.in(idList))
                .execute();
    }

    public HashMap<String, List> divisionMap() {
        HashMap<String, List> map = new HashMap<>();
        // 所有省
        List<DivisionEntity> provinceDivisions = PlatformAPI.getDivisionAPI().getSubDivisions("root");
        for (DivisionEntity province : provinceDivisions) {
            String provinceName = province.getDivisionName();
            // 市
            List<DivisionEntity> cities = PlatformAPI.getDivisionAPI().getSubDivisions(province.getDivisionId());
            ArrayList<String> cityNames = new ArrayList<>();
            for (DivisionEntity city : cities) {
                String cityName = city.getDivisionName();
                cityNames.add(cityName);
                // 不为直辖市
                if (!"北京市".equals(provinceName) && !"天津市".equals(provinceName) && !"上海市".equals(provinceName) && !"重庆市".equals(provinceName)) {
                    // 获取市下面的区县
                    List<DivisionEntity> areas = PlatformAPI.getDivisionAPI().getSubDivisions(city.getDivisionId());
                    ArrayList<String> areaNames = new ArrayList<>();
                    for (DivisionEntity area : areas) {
                        String areaName = area.getDivisionName();
                        areaNames.add(areaName);
                    }
                    map.put(cityName, areaNames);
                }
            }
            // 省对应下面的市(直辖市-对应的是区)
            map.put(provinceName, cityNames);
        }
        return map;
    }

    @Override
    public String exportExcel(String taskName, String taskId, MultipartFile file, HttpServletResponse response) {
        // 单例初始化省市区map
        if (divisionMap == null) {
            synchronized (this) {
                if (divisionMap == null) {
                    divisionMap = divisionMap();
                }
            }
        }
        try {
            // 返回的消息
            StringBuilder returnMsg = new StringBuilder();
            // 导入的参数信息
            ImportParams params = new ImportParams();
            // 设置简析的第一行
            params.setHeadRows(1);
            // 是否需要校验
            params.setNeedVerify(true);
            params.setVerifyHandler(new OtherStructureCheck(divisionMap));
            // 获取到Excel数据
            ExcelImportResult<FwOtherStructureVo> result = ExcelImportUtil.importExcelMore(file.getInputStream(), FwOtherStructureVo.class, params);
            List<FwOtherStructureVo> list = result.getList();
            // Excel条数据
            int firstList = list.size();
            StringBuilder sb = new StringBuilder();
            // 重复后失败条数
            int failCount = saveFwOtherStrucure(taskName, taskId, list, sb);
            if (failCount > 0) {
                // result.getFailList().size()为保存时出错的条数
                int failList = firstList + result.getFailList().size() - list.size();
                returnMsg.append("成功导入" + (result.getList().size() - failCount) + "条，失败" + (failList + failCount) + "条<br/>");
                returnMsg.append("样本编码" + failCount + "存在重复数据<br/>");
                returnMsg.append(sb);
            } else {
                returnMsg.append("成功导入" + (result.getList().size() - failCount) + "条，失败" + (result.getFailList().size() + failCount) + "条<br/>");
                returnMsg.append(sb);
            }
            if (result.isVerifyFail()) {
                // 校验返回失败行信息
                Iterator<FwOtherStructureVo> iterator = result.getFailList().iterator();
                while (iterator.hasNext()) {
                    FwOtherStructureVo fwOtherStructureVo = iterator.next();
                    String error = "";
                    returnMsg.append("第" + fwOtherStructureVo.getRowNum() + "行" + fwOtherStructureVo.getErrorMsg() + "<br/>");
                    returnMsg.append(error);
                }
            }
            return returnMsg.toString();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return "导入失败，请检查数据正确性";
        }
    }

    @Transactional
    @Override
    public void updateFileId(String formId, String fileId) {
        FwOtherStructureEntity fwOtherStructureEntity = findById(formId);

        if (!StringUtils.isEmpty(fwOtherStructureEntity)) {
            otherStructureRepository.update(formId, fileId);
        }
    }
    public int saveFwOtherStrucure(String taskName, String taskId, List<FwOtherStructureVo> list, StringBuilder message) {
        int count = 0;
        for (int i = 0; i < list.size(); i++) {
            FwOtherStructureEntity fwOtherStructure = new FwOtherStructureEntity();
            FwOtherStructureVo otherStructureVo = list.get(i);
            // 将VO数据映射拷贝到库表中
            BeanUtils.copyProperties(otherStructureVo, fwOtherStructure);
            String isValid="0";
            // 根据样本编号判断重复导入性
            FwOtherStructureEntity byOtherStructureNum = otherStructureRepository.findByOtherStructureNumAndDelFlag(otherStructureVo.getOtherStructureNum(),isValid);
            if (!StringUtils.isEmpty(byOtherStructureNum)) {
                message.append("样本编码" + otherStructureVo.getOtherStructureNum() + "已重复");
                ++count;
            } else {
                fwOtherStructure.setTaskId(taskId);
                fwOtherStructure.setTaskName(taskName);
                //导入数据后台生成编号
                String code = DivisionCache.structureCode();
                fwOtherStructure.setOtherStructureNum(code);
                save(fwOtherStructure);
            }
        }
        return count;
    }

    @Override
    public long count(AnalysisQueryVo analysisQueryVo) {
        // 查询条件
        Specification querySpecification = new Specification<FwOtherStructureEntity>() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root<FwOtherStructureEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(analysisQueryVo)) {
                    // 省
                    String belongtoProvince = analysisQueryVo.getBelongtoProvince();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoProvince)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoProvince"), belongtoProvince));
                    }
                    // 市
                    String belongtoCity = analysisQueryVo.getBelongtoCity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoCity)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoCity"), belongtoCity));
                    }
                    // 区
                    String belongtoArea = analysisQueryVo.getBelongtoArea();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoArea)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoArea"), belongtoArea));
                    }
                    //建筑年代
                    String buildingAge = analysisQueryVo.getBuildingAge();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(buildingAge)) {
                        predicates.add(criteriaBuilder.equal(root.get("buildingAge"), buildingAge));
                    }
                    //任务名称
                    String taskName = analysisQueryVo.getTaskName();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(taskName)) {
                        String[] strArray = taskName.split(",");
                        List<String> list = Arrays.asList(strArray);
                        if (list != null && list.size() > 0){
                            predicates.add(root.get("taskName").in(list));
                        }
                    }
                    //抗震设防烈度
                    String nowFortificationIntensity = analysisQueryVo.getNowFortificationIntensity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(nowFortificationIntensity)) {
                        predicates.add(criteriaBuilder.equal(root.get("fortifyStandard"), nowFortificationIntensity));
                    }
                    //外墙厚度
                    String outWallThick = analysisQueryVo.getOutWallThick();
                    if (!StringUtils.isEmpty(outWallThick)) {
                        //如果外墙厚度为“外墙厚度<=120mm”
                        if (Constant.WAI_WALL_LESS_120.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.le(root.get("outWallThick"), 120));
                        }
                        //如果外墙厚度为“外墙厚度120mm-240mm”
                        if (Constant.WAI_WALL_BETWEEN_120_240.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("outWallThick"), 120, 240));
                        }
                        //如果外墙厚度为“外墙厚度240mm-370mm”
                        if (Constant.WAI_WALL_BETWEEN_240_370.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("outWallThick"), 240, 370));
                        }
                        //如果外墙厚度为“外墙厚度>=370mm”
                        if (Constant.WAI_WALL_MORE_370.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.ge(root.get("outWallThick"), 370));
                        }
                    }
                    //内墙厚度
                    String inWallThick = analysisQueryVo.getInWallThick();
                    if (!StringUtils.isEmpty(inWallThick)) {
                        //如果内墙厚度为“内墙厚度<=120mm”
                        if (Constant.WITHIN_WALL_LESS_120.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.le(root.get("inWallThick"), 120));
                        }
                        //如果内墙厚度为“内墙厚度120mm-240mm”
                        if (Constant.WITHIN_WALL_BETWEEN_120_240.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("inWallThick"), 120, 240));
                        }
                        //如果内墙厚度为“内墙厚度240mm-370mm”
                        if (Constant.WITHIN_WALL_BETWEEN_240_370.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("inWallThick"), 240, 370));
                        }
                        //如果内墙厚度为“内墙厚度>=370mm”
                        if (Constant.WITHIN_WALL_MORE_370.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.ge(root.get("inWallThick"), 370));
                        }
                    }
                    //墙体材质
                    String wallMaterial = analysisQueryVo.getWallMaterial();
                    if (!StringUtils.isEmpty(wallMaterial)) {
                        predicates.add(criteriaBuilder.equal(root.get("wallMaterial"), wallMaterial));
                    }
                    //剪力墙混凝土强度等级
                    String jlqhntqdLevel = analysisQueryVo.getJlqhntqdLevel();
                    if (!StringUtils.isEmpty(jlqhntqdLevel)) {
                        predicates.add(criteriaBuilder.equal(root.get("jlqhntqdLevel"), jlqhntqdLevel));
                    }
                    /*//剪力墙厚度
                    String shearwellThickness = analysisQueryVo.getShearwellThickness();
                    if (!StringUtils.isEmpty(shearwellThickness)) {
                        //剪力墙厚度<=160mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_LESS_160.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.le(root.get("shearwellThickness"), 160));
                        }
                        //剪力墙厚度160mm-200mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_160_200.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 160, 200));
                        }
                        //剪力墙厚度200mm-400mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_200_400.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 200, 400));
                        }
                        //剪力墙厚度400mm-700mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_400_700.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 400, 700));
                        }
                        //剪力墙厚度>=700mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_MORE_700.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.ge(root.get("shearwellThickness"), 700));
                        }
                    }*/
                    //剪力墙最大间距
                    String jlqzdSpan = analysisQueryVo.getJlqzdSpan();
                    if (!StringUtils.isEmpty(jlqzdSpan)) {
                        //剪力墙最大间距<=30m
                        if (Constant.JLQZD_SPAN_LESS_30.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.le(root.get("jlqzdSpan"), 30));
                        }
                        //剪力墙最大间距30-40m
                        if (Constant.JLQZD_SPAN_BETWEEN_30_40.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 30, 40));
                        }
                        //剪力墙最大间距40-50m
                        if (Constant.JLQZD_SPAN_BETWEEN_40_50.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 40, 50));
                        }
                        //剪力墙最大间距50-60m
                        if (Constant.JLQZD_SPAN_BETWEEN_50_60.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 50, 60));
                        }
                        //剪力墙最大间距>=60m
                        if (Constant.JLQZD_SPAN_MORE_60.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.ge(root.get("jlqzdSpan"), 60));
                        }
                    }

                    //砂浆类型
                    String mortarType = analysisQueryVo.getMortarType();
                    if (!StringUtils.isEmpty(mortarType)) {
                        predicates.add(criteriaBuilder.equal(root.get("mortarType"), mortarType));
                    }
                    //砂浆强度
                    String mortarStrength = analysisQueryVo.getMortarStrength();
                    if (!StringUtils.isEmpty(mortarStrength)) {
                        predicates.add(criteriaBuilder.equal(root.get("mortarStrength"), mortarStrength));
                    }
                    //屋盖类别
                    String roofType = analysisQueryVo.getRoofType();
                    if (!StringUtils.isEmpty(roofType)) {
                        predicates.add(criteriaBuilder.equal(root.get("roofType"), roofType));
                    }
                    //楼盖类别
                    String floorType = analysisQueryVo.getFloorType();
                    if (!StringUtils.isEmpty(floorType)) {
                        predicates.add(criteriaBuilder.equal(root.get("floorType"), floorType));
                    }
                    //圈梁设置
                    String jlInstall = analysisQueryVo.getJlInstall();
                    if (!StringUtils.isEmpty(jlInstall)) {
                        predicates.add(criteriaBuilder.equal(root.get("jlInstall"), jlInstall));
                    }
                }
                // 有效标识，即为有效的
                predicates.add(criteriaBuilder.equal(root.get("delFlag"), Constant.IS_VALID_YES));
                //审核通过的
                predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                return criteriaBuilder.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
            }
        };
        return otherStructureRepository.count(querySpecification);
    }

    @Override
    public double area(AnalysisQueryVo analysisQueryVo) {
        // 查询条件
        Specification querySpecification = new Specification<FwOtherStructureEntity>() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root<FwOtherStructureEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(analysisQueryVo)) {
                    // 省
                    String belongtoProvince = analysisQueryVo.getBelongtoProvince();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoProvince)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoProvince"), belongtoProvince));
                    }
                    // 市
                    String belongtoCity = analysisQueryVo.getBelongtoCity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoCity)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoCity"), belongtoCity));
                    }
                    // 区
                    String belongtoArea = analysisQueryVo.getBelongtoArea();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoArea)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoArea"), belongtoArea));
                    }
                    //建筑年代
                    String buildingAge = analysisQueryVo.getBuildingAge();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(buildingAge)) {
                        predicates.add(criteriaBuilder.equal(root.get("buildingAge"), buildingAge));
                    }
                    //任务名称
                    String taskName = analysisQueryVo.getTaskName();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(taskName)) {
                        String[] strArray = taskName.split(",");
                        List<String> list = Arrays.asList(strArray);
                        if (list != null && list.size() > 0){
                            predicates.add(root.get("taskName").in(list));
                        }
                    }
                    //抗震设防烈度
                    String nowFortificationIntensity = analysisQueryVo.getNowFortificationIntensity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(nowFortificationIntensity)) {
                        predicates.add(criteriaBuilder.equal(root.get("fortifyStandard"), nowFortificationIntensity));
                    }
                    //外墙厚度
                    String outWallThick = analysisQueryVo.getOutWallThick();
                    if (!StringUtils.isEmpty(outWallThick)) {
                        //如果外墙厚度为“外墙厚度<=120mm”
                        if (Constant.WAI_WALL_LESS_120.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.le(root.get("outWallThick"), 120));
                        }
                        //如果外墙厚度为“外墙厚度120mm-240mm”
                        if (Constant.WAI_WALL_BETWEEN_120_240.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("outWallThick"), 120, 240));
                        }
                        //如果外墙厚度为“外墙厚度240mm-370mm”
                        if (Constant.WAI_WALL_BETWEEN_240_370.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("outWallThick"), 240, 370));
                        }
                        //如果外墙厚度为“外墙厚度>=370mm”
                        if (Constant.WAI_WALL_MORE_370.equals(outWallThick)) {
                            predicates.add(criteriaBuilder.ge(root.get("outWallThick"), 370));
                        }
                    }
                    //内墙厚度
                    String inWallThick = analysisQueryVo.getInWallThick();
                    if (!StringUtils.isEmpty(inWallThick)) {
                        //如果内墙厚度为“内墙厚度<=120mm”
                        if (Constant.WITHIN_WALL_LESS_120.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.le(root.get("inWallThick"), 120));
                        }
                        //如果内墙厚度为“内墙厚度120mm-240mm”
                        if (Constant.WITHIN_WALL_BETWEEN_120_240.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("inWallThick"), 120, 240));
                        }
                        //如果内墙厚度为“内墙厚度240mm-370mm”
                        if (Constant.WITHIN_WALL_BETWEEN_240_370.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.between(root.get("inWallThick"), 240, 370));
                        }
                        //如果内墙厚度为“内墙厚度>=370mm”
                        if (Constant.WITHIN_WALL_MORE_370.equals(inWallThick)) {
                            predicates.add(criteriaBuilder.ge(root.get("inWallThick"), 370));
                        }
                    }
                    //墙体材质
                    String wallMaterial = analysisQueryVo.getWallMaterial();
                    if (!StringUtils.isEmpty(wallMaterial)) {
                        predicates.add(criteriaBuilder.equal(root.get("wallMaterial"), wallMaterial));
                    }
                    //剪力墙混凝土强度等级
                    String jlqhntqdLevel = analysisQueryVo.getJlqhntqdLevel();
                    if (!StringUtils.isEmpty(jlqhntqdLevel)) {
                        predicates.add(criteriaBuilder.equal(root.get("jlqhntqdLevel"), jlqhntqdLevel));
                    }
                    /*//剪力墙厚度
                    String shearwellThickness = analysisQueryVo.getShearwellThickness();
                    if (!StringUtils.isEmpty(shearwellThickness)) {
                        //剪力墙厚度<=160mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_LESS_160.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.le(root.get("shearwellThickness"), 160));
                        }
                        //剪力墙厚度160mm-200mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_160_200.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 160, 200));
                        }
                        //剪力墙厚度200mm-400mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_200_400.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 200, 400));
                        }
                        //剪力墙厚度400mm-700mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_BETWEEN_400_700.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.between(root.get("shearwellThickness"), 400, 700));
                        }
                        //剪力墙厚度>=700mm
                        if (Constant.HEIGHT_SHEARWELL_THICKNESS_MORE_700.equals(shearwellThickness)) {
                            predicates.add(criteriaBuilder.ge(root.get("shearwellThickness"), 700));
                        }
                    }*/
                    //剪力墙最大间距
                    String jlqzdSpan = analysisQueryVo.getJlqzdSpan();
                    if (!StringUtils.isEmpty(jlqzdSpan)) {
                        //剪力墙最大间距<=30m
                        if (Constant.JLQZD_SPAN_LESS_30.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.le(root.get("jlqzdSpan"), 30));
                        }
                        //剪力墙最大间距30-40m
                        if (Constant.JLQZD_SPAN_BETWEEN_30_40.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 30, 40));
                        }
                        //剪力墙最大间距40-50m
                        if (Constant.JLQZD_SPAN_BETWEEN_40_50.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 40, 50));
                        }
                        //剪力墙最大间距50-60m
                        if (Constant.JLQZD_SPAN_BETWEEN_50_60.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.between(root.get("jlqzdSpan"), 50, 60));
                        }
                        //剪力墙最大间距>=60m
                        if (Constant.JLQZD_SPAN_MORE_60.equals(jlqzdSpan)) {
                            predicates.add(criteriaBuilder.ge(root.get("jlqzdSpan"), 60));
                        }
                    }
                    //砂浆类型
                    String mortarType = analysisQueryVo.getMortarType();
                    if (!StringUtils.isEmpty(mortarType)) {
                        predicates.add(criteriaBuilder.equal(root.get("mortarType"), mortarType));
                    }
                    //砂浆强度
                    String mortarStrength = analysisQueryVo.getMortarStrength();
                    if (!StringUtils.isEmpty(mortarStrength)) {
                        predicates.add(criteriaBuilder.equal(root.get("mortarStrength"), mortarStrength));
                    }
                    //屋盖类别
                    String roofType = analysisQueryVo.getRoofType();
                    if (!StringUtils.isEmpty(roofType)) {
                        predicates.add(criteriaBuilder.equal(root.get("roofType"), roofType));
                    }
                    //楼盖类别
                    String floorType = analysisQueryVo.getFloorType();
                    if (!StringUtils.isEmpty(floorType)) {
                        predicates.add(criteriaBuilder.equal(root.get("floorType"), floorType));
                    }
                    //圈梁设置
                    String jlInstall = analysisQueryVo.getJlInstall();
                    if (!StringUtils.isEmpty(jlInstall)) {
                        predicates.add(criteriaBuilder.equal(root.get("jlInstall"), jlInstall));
                    }
                }
                // 有效标识，即为有效的
                predicates.add(criteriaBuilder.equal(root.get("delFlag"), Constant.IS_VALID_YES));
                //审核通过的
                predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                return criteriaBuilder.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
            }
        };
        List<FwOtherStructureEntity> all = otherStructureRepository.findAll(querySpecification);
        double count = 0.00;
        for (FwOtherStructureEntity fwOtherStructureEntity : all) {
            double buildingArea = 0.00;
            if (!PlatformObjectUtils.isEmpty(fwOtherStructureEntity.getBuildingArea())) {
                buildingArea = fwOtherStructureEntity.getBuildingArea().doubleValue();
                if (!PlatformObjectUtils.isEmpty(fwOtherStructureEntity.getFloorNum())) {
                    buildingArea = fwOtherStructureEntity.getBuildingArea().doubleValue() *
                            fwOtherStructureEntity.getFloorNum().intValue();
                }
            }
            count += buildingArea;
        }
        Double.parseDouble(String.format("%.3f",count));
        return  Double.parseDouble(String.format("%.3f",count));
    }

    @Override
    public void export(List<String> idList, HttpServletResponse response) {
        List<FwOtherStructureEntity> list = otherStructureRepository.findInIdList(idList);
        // 深拷贝
        ArrayList<FwOtherStructureVo> vos = new ArrayList<>();
        for (FwOtherStructureEntity otherStructureEntity : list) {
            if(otherStructureEntity.getStatus().equals("1")){
                otherStructureEntity.setStatus("未审核");
            }else if(otherStructureEntity.getStatus().equals("2")){
                otherStructureEntity.setStatus("审核未通过");
            }else if(otherStructureEntity.getStatus().equals("3")){
                otherStructureEntity.setStatus("审核通过");
            }else if(otherStructureEntity.getStatus().equals("4")){
                otherStructureEntity.setStatus("省级退回");
            }else {
                otherStructureEntity.setStatus("中心退回");
            }
            String detailFile = otherStructureEntity.getDetailFile();
            StringBuilder file = new StringBuilder();
            if(org.apache.commons.lang3.StringUtils.isNotBlank(detailFile)){
                //获取数据真实的附件信息
                List<SysAttachmentEntity> byAttachIdsAndIsValid = sysAttachment.findByAttachIdsAndIsValid(Arrays.asList(detailFile.split(",")));
                if(PlatformObjectUtils.isNotEmpty(byAttachIdsAndIsValid)){
                    for (SysAttachmentEntity sysAttachmentEntity : byAttachIdsAndIsValid) {
                        String attachPath = sysAttachmentEntity.getAttachPath();
                        attachPath = attachPath.replace("/","");
                        file.append(attachPath).append(",");
                    }
                }
            }
            if(file.length()>0){
                String fileName = file.substring(0, file.length() - 1);
                otherStructureEntity.setDetailFile(fileName);
            }
            FwOtherStructureVo vo = new FwOtherStructureVo();
            BeanUtils.copyProperties(otherStructureEntity, vo);
            vos.add(vo);
        }
        // 导出
        EasyPoiExcelUtil.exportExcel(vos, "其它结构信息统计", "其它结构信息", FwOtherStructureVo.class, "其它结构.xls", response);
    }

    @Override
    public long buildingCount(AnalysisQueryVo analysisQueryVo) {
        // 查询条件
        Specification querySpecification = new Specification<FwStructureFormEntity>() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root<FwStructureFormEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(analysisQueryVo)) {
                    // 省
                    String belongtoProvince = analysisQueryVo.getBelongtoProvince();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoProvince)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoProvince"), belongtoProvince));
                    }
                    // 市
                    String belongtoCity = analysisQueryVo.getBelongtoCity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoCity)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoCity"), belongtoCity));
                    }
                    // 区
                    String belongtoArea = analysisQueryVo.getBelongtoArea();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoArea)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoArea"), belongtoArea));
                    }
                    //建筑年代
                    String buildingAge = analysisQueryVo.getBuildingAge();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(buildingAge)) {
                        predicates.add(criteriaBuilder.equal(root.get("buildingAge"), buildingAge));
                    }
                    //任务名称
                    String taskName = analysisQueryVo.getTaskName();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(taskName)) {
                        String[] strArray = taskName.split(",");
                        List<String> list = Arrays.asList(strArray);
                        if (list != null && list.size() > 0){
                            predicates.add(root.get("taskName").in(list));
                        }
                    }
                    // 审批类型
                    String status = analysisQueryVo.getStatus();
                    if (!StringUtils.isEmpty(status)) {
                        if ("审核通过".equals(status)) {
                            // 若为审核通过，查询status状态为3
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                        } else if ("审核不通过".equals(status)) {
                            // 若为审核不通过，查询status状态为2
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_NOT));
                        } else {
                            //若为审核不通过，查询status状态为2
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.DAI_SP));
                        }
                    }else {
                        //默认查询非未提交的
                        //predicates.add(criteriaBuilder.in(root.get("status"), (Constant.DAI_SP,Constant.DAI_SP));
                        CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("status"));
                        in.value(Constant.DAI_SP);
                        in.value(Constant.SP_NOT);
                        in.value(Constant.SP_YES);
                        predicates.add(in);
                    }
                }
                // 有效标识，即为有效的
                predicates.add(criteriaBuilder.equal(root.get("delFlag"), Constant.IS_VALID_YES));
                //审核通过的
                //predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                predicates.add(criteriaBuilder.equal(root.get("structureType"), Constant.OTHER_STRUCTURE));
                return criteriaBuilder.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
            }
        };
        return fwStructureFormRepository.count(querySpecification);
    }

    @Override
    public double otherAreaCount(AnalysisQueryVo analysisQueryVo) {
        // 查询条件
        Specification querySpecification = new Specification<FwOtherStructureEntity>() {
            @Override
            public javax.persistence.criteria.Predicate toPredicate(Root<FwOtherStructureEntity> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<javax.persistence.criteria.Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(analysisQueryVo)) {
                    // 省
                    String belongtoProvince = analysisQueryVo.getBelongtoProvince();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoProvince)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoProvince"), belongtoProvince));
                    }
                    // 市
                    String belongtoCity = analysisQueryVo.getBelongtoCity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoCity)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoCity"), belongtoCity));
                    }
                    // 区
                    String belongtoArea = analysisQueryVo.getBelongtoArea();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(belongtoArea)) {
                        predicates.add(criteriaBuilder.equal(root.get("belongtoArea"), belongtoArea));
                    }
                    //建筑年代
                    String buildingAge = analysisQueryVo.getBuildingAge();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(buildingAge)) {
                        predicates.add(criteriaBuilder.equal(root.get("buildingAge"), buildingAge));
                    }
                    //任务名称
                    String taskName = analysisQueryVo.getTaskName();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(taskName)) {
                        predicates.add(criteriaBuilder.equal(root.get("taskName"), taskName));
                    }
                    //抗震设防烈度
                    String nowFortificationIntensity = analysisQueryVo.getNowFortificationIntensity();
                    if (!org.apache.commons.lang3.StringUtils.isEmpty(nowFortificationIntensity)) {
                        predicates.add(criteriaBuilder.equal(root.get("fortifyStandard"), nowFortificationIntensity));
                    }
                    // 审批类型
                    String status = analysisQueryVo.getStatus();
                    if (!StringUtils.isEmpty(status)) {
                        if ("审核通过".equals(status)) {
                            // 若为审核通过，查询status状态为3
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                        } else if ("审核不通过".equals(status)) {
                            // 若为审核不通过，查询status状态为2
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_NOT));
                        } else {
                            //若为审核不通过，查询status状态为2
                            predicates.add(criteriaBuilder.equal(root.get("status"), Constant.DAI_SP));
                        }
                    }else {
                        //默认查询非未提交的
                        //predicates.add(criteriaBuilder.in(root.get("status"), (Constant.DAI_SP,Constant.DAI_SP));
                        CriteriaBuilder.In<Object> in = criteriaBuilder.in(root.get("status"));
                        in.value(Constant.DAI_SP);
                        in.value(Constant.SP_NOT);
                        in.value(Constant.SP_YES);
                        predicates.add(in);
                    }
                }
                // 有效标识，即为有效的
                predicates.add(criteriaBuilder.equal(root.get("delFlag"), Constant.IS_VALID_YES));
                //审核通过的
                //predicates.add(criteriaBuilder.equal(root.get("status"), Constant.SP_YES));
                return criteriaBuilder.and(predicates.toArray(new javax.persistence.criteria.Predicate[predicates.size()]));
            }
        };
        List<FwOtherStructureEntity> all = otherStructureRepository.findAll(querySpecification);
        double count = 0.00;
        for (FwOtherStructureEntity fwOtherStructureEntity : all) {
            double buildingArea = 0.00;
            if (!StringUtils.isEmpty(fwOtherStructureEntity.getBuildingArea())) {
                buildingArea = fwOtherStructureEntity.getBuildingArea();
            }
            count += buildingArea;
        }
        Double.parseDouble(String.format("%.3f",count));
        return  Double.parseDouble(String.format("%.3f",count));
    }
}
